//
//  MNBaseReq.swift
//  SwiftDemo
//
//  Created by jacknan on 2019/6/28.
//  Copyright © 2019 upbest. All rights reserved.
// 请求基类

import UIKit
import Alamofire
import HandyJSON


/// 上传文件模型
struct MNUploadFileModel {
    var data: Data?
    var name = "file"
    var type: String = ""
    var fileName: String = "file"
}


class MNBaseReq: HandyJSON {
    
    ///请求方式
    var method: HTTPMethod = .get
    
    /// 请求的完整url，eg. https://...
    var reqUrl: String?
    
    /// 路由路径 最终会拼接到baseUrl之后, 如设置reqUrl 则优先使用reqUrl 此值无效
    var routingPath: String?
    
    /// 附加请求头参数，在请求结束会从sessionManager移除
    var httpHeaders = [String:String]()
    
    /// 请求超时时间 nil则使用默认值
    var timeoutInterval:TimeInterval?
    
    /// 上传的文件模型
    var uploadFiles: [MNUploadFileModel]?
    
    /// 本次请求返回的request任务
    var request: DataRequest?
    
    /// 请求标识，返回对象会保持统一，用于本次app生命周期的请求和返回的唯一标识
    var identifier: Int = 0
    
    ///返回请求地址
    var url:URL {
        get {
            var Url:URL? = nil
            if let urlStr = reqUrl {
                Url = URL.init(string: urlStr)
            }else if let path = routingPath {
                Url = URL.init(string: BaseUrl + path)
            }else{
                assert(false, "未配置请求地址!")
                Url = URL.init(string: BaseUrl)
            }
            return Url!
        }
    }
    
    /// 返回的class 默认遵循命名规范，优先使用设置的class,找不到则返回BaseRsp
    func rspClass() -> HandyJSON.Type {
        let reqStr = typeName(object: self)
        if reqStr.hasSuffix("Req") {
            var rspStr = String(reqStr.prefix(reqStr.count - 3)) + "Rsp"
            if let projectStr = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String {
                rspStr = "\(projectStr).\(rspStr)"
            }
            
            guard let cls = NSClassFromString(rspStr) else {
                return MNBaseRsp.self
            }
            return cls as? (HandyJSON.Type) ?? MNBaseRsp.self
        }
        return MNBaseRsp.self
    }
    
    /// 排除辅助属性 不解析
    func mapping(mapper: HelpingMapper) {
        mapper >>> self.request
        mapper >>> self.reqUrl
        mapper >>> self.routingPath
        mapper >>> self.httpHeaders
        mapper >>> self.timeoutInterval
        mapper >>> self.method
        mapper >>> self.uploadFiles
        mapper >>> self.identifier
    }
    
    required init() {}
}

func typeName(object: Any)-> String {
    let typeStr = String(describing: type(of: object))
    let rspStr: String! = typeStr.components(separatedBy: ".").last ?? ""
    return rspStr
}
